﻿-- Author  : Kurapica
-- Create Date : 2009/11/10

do
	IGAS:NewAddon("IGAS_Studio")
		
	-- Toc format
	_TOC_FORMAT = {
		{
			-- Addon Name
			["Name"] = "Name",
			["Type"] = "String",
		},
		{
			-- Interface
			["Name"] = "Interface",
			["Type"] = "Number",
			["Func"] = function() return tostring((select(4, GetBuildInfo()))) end
		},
		{
			-- Title
			["Name"] = "Title",
			["Type"] = "Set",
		},
		{
			-- Notes
			["Name"] = "Notes",
			["Type"] = "Set",
		},
		{
			-- RequiredDeps
			["Name"] = "RequiredDeps",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
		},
		{
			-- OptionalDeps
			["Name"] = "OptionalDeps",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
			["Default"] = "IGAS",
			["Validate"] = function(text)
				local stext = gsub(text, "%s", "")
				local chk = {strsplit(",", stext)}
				
				for i = 1, #chk do
					if chk[i] == "IGAS" then
						return text
					end
				end
				
				if #chk > 0 then
					return "IGAS, "..text
				else
					return "IGAS"
				end
			end,
		},
		{
			-- LoadOnDemand
			["Name"] = "LoadOnDemand",
			["Type"] = "Boolean",
			["True"] = "1",
			["False"] = "0",
		},
		{
			-- LoadWith
			["Name"] = "LoadWith",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
		},
		{
			-- LoadManagers
			["Name"] = "LoadManagers",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
		},
		{
			-- SavedVariables
			["Name"] = "SavedVariables",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
		},
		{
			-- SavedVariablesPerCharacter
			["Name"] = "SavedVariablesPerCharacter",
			["Type"] = "String",
			["Info"] = L["Using \",\" to separate"],
		},
		{
			-- DefaultState
			["Name"] = "DefaultState",
			["Type"] = "Boolean",
			["True"] = "enabled",
			["False"] = "disabled",
		},
		{
			-- Secure
			["Name"] = "Secure",
			["Type"] = "Boolean",
			["True"] = "1",
			["False"] = "0",
		},
		-- Non-Standard Tags 
		{
			-- Addon Author
			["Name"] = "Author",
			["Type"] = "String",
		},
		{
			-- Addon Version
			["Name"] = "Version",
			["Type"] = "String",
		},
		{
			-- Addon eMail
			["Name"] = "eMail",
			["Type"] = "String",
		},
		{
			-- Addon URL
			["Name"] = "URL",
			["Type"] = "String",
		},
	}
	
	-- AddonInfo Form
	local frm = CreateFrame("Form", "AddonInfo", coreF)
	frm.Caption = L["Addon Info"]	
	frm.Width = 540
	frm.Height = 500
	frm.Visible = false
	
	------------------------------------------------
	-- Layout
	------------------------------------------------
	local sf = CreateFrame("ScrollForm", "ScrollForm", frm)
	sf:SetPoint("TOPLEFT", frm, "TOPLEFT", 10, -25)
	sf:SetPoint("BOTTOMRIGHT", frm, "BOTTOMRIGHT", -10, 50)
	local Container = sf.Container
	
	local btnCancel = CreateFrame("NormalButton", "btnCancel", frm)
	btnCancel.Width = 100
	btnCancel.Height = 24
	btnCancel.Style = "NORMAL"
	btnCancel:SetPoint("BOTTOMRIGHT", frm, "BOTTOMRIGHT", -10, 24)
	btnCancel.Text = L["Cancel"]
	
	local btnSave = CreateFrame("NormalButton", "btnSave", frm)
	btnSave.Width = 100
	btnSave.Height = 24
	btnSave.Style = "NORMAL"
	btnSave:SetPoint("RIGHT", btnCancel, "LEFT", -10, 0)
	btnSave.Text = L["Save"]
	
	local _Last = nil
	
	for _, v in ipairs(_TOC_FORMAT) do
		if v.Type == "String" or v.Type == "Number" then
			-- Label
			local label = CreateFrame("FontString", "lbl"..v.Name, Container, "OVERLAY", "GameFontNormal")
			if _Last then
				label:SetPoint("TOP", _Last, "BOTTOM", 0, -10)
			else
				label:SetPoint("TOP", Container, "TOP", 0, -10)
			end
			label:SetPoint("LEFT", Container, "LEFT", 10, 0)
			label.JustifyH = "LEFT"
			label.Width = 150
			label.Height = 25
			label.Text = L[v.Name]
		 
			-- Input TextBox
			local textbox = CreateFrame("SingleTextBox", "txt"..v.Name, Container)
			textbox:SetPoint("LEFT", label, "RIGHT")
			textbox.Style = "LIGHT"
			textbox.Width = 200
			textbox.Height = 25
			if v.Type == "Number" then
				textbox.NumericOnly = true
			end
			_Last = textbox
			
			-- Update Button
			if v.Func then				
				local btnUpdate = CreateFrame("NormalButton", "btn"..v.Name, Container)
				btnUpdate:SetPoint("LEFT", _Last, "RIGHT")
				btnUpdate.Style = "NORMAL"
				btnUpdate.Width = 100
				btnUpdate.Height = 25
				btnUpdate.Text = L["Update"]
				
				function btnUpdate:OnClick()
					textbox.Text = tostring(v.Func())
				end
				_Last = btnUpdate
			end
			
			-- Label Info
			if v.Info then			
				local lblInfo = CreateFrame("FontString", "lblInfo"..v.Name, Container ,"OVERLAY","GameFontNormal")
				lblInfo:SetPoint("LEFT", _Last, "RIGHT")
				lblInfo:SetPoint("RIGHT", Container, "RIGHT")
				lblInfo.JustifyH = "LEFT"
				lblInfo.Height = 25
				lblInfo.Text = L[v.Info]
			end
			
			_Last = label
		elseif v.Type == "Set" then
			-- Label
			local label = CreateFrame("FontString", "lbl"..v.Name, Container ,"OVERLAY","GameFontNormal")
			if _Last then
				label:SetPoint("TOP", _Last, "BOTTOM", 0, -10)
			else
				label:SetPoint("TOP", Container, "TOP", 0, -10)
			end
			label:SetPoint("LEFT", Container, "LEFT", 10, 0)
			label.JustifyH = "LEFT"
			label.Width = 150
			label.Height = 25
			label.Text = L[v.Name]
			
			-- Set
			local set = CreateFrame(Widget.Set, "set"..v.Name, Container)
			set:SetPoint("TOPLEFT", label , "TOPRIGHT")
			set.Prefix = v.Name
			
			_Last = set
		elseif v.Type == "Boolean" then
			local label = CreateFrame("FontString", "lbl"..v.Name, Container ,"OVERLAY","GameFontNormal")
			if _Last then
				label:SetPoint("TOP", _Last, "BOTTOM", 0, -10)
			else
				label:SetPoint("TOP", Container, "TOP", 0, -10)
			end
			label:SetPoint("LEFT", Container, "LEFT", 10, 0)
			label.JustifyH = "LEFT"
			label.Width = 150
			label.Height = 25
			label.Text = L[v.Name]
			
			-- CheckBox
			local chkBox = CreateFrame("CheckBox", "chk"..v.Name, Container)
			chkBox:SetPoint("LEFT", label, "RIGHT")
			chkBox.TrueText = v.True
			chkBox.FalseText = v.False
			chkBox.Checked = false
			
			_Last = label
		end
	end
	
	_Last = nil
	sf:FixHeight()
	
	------------------------------------------------
	-- Scripts
	------------------------------------------------
	local substr = {}
	
	local function Decode(var)
		return (substr[var] and substr[var]) or ""
	end
	
	local function GetContent(script)
		return gsub(script, "@(%a+)", Decode)
	end
	
	local _AddonScript = [[
IGAS:NewAddon("@Addon")

]]
	local _InitScript = [[
-- Addon Initialize
IGAS:NewAddon("@Addon")

-- Localization
L = IGAS:NewLocal("@Addon")

-- Logger
Log = IGAS:NewLogger("@Addon")

Log.TimeFormat = "%X"
Log:SetPrefix(1, "[@Addon][Trace]")
Log:SetPrefix(2, "[@Addon][Debug]")
Log:SetPrefix(3, "[@Addon][Info]")
Log:SetPrefix(4, "[@Addon][Warn]")
Log:SetPrefix(5, "[@Addon][Error]")
Log:SetPrefix(6, "[@Addon][Fatal]")

Log:AddHandler(print)

-- Remember to modify this when you release this addon
Log.LogLevel = 1

-- Special Global Functions
CreateFrame = IGAS.GUI.CreateFrame

-- SavedVariables
]]
	local _SaveVScript = [[
_Addon:AddSavedVariable("@SavedVariable")
]]

	local function GetSaveVariables(addon)
		local str = ""
		
		if addon[0].SavedVariables then
			for sav in gmatch(addon[0].SavedVariables, "[%w_]+") do
				substr["SavedVariable"] = sav
				str = str..GetContent(_SaveVScript)
			end
		end
		if addon[0].SavedVariablesPerCharacter then
			for sav in gmatch(addon[0].SavedVariablesPerCharacter, "[%w_]+") do
				substr["SavedVariable"] = sav
				str = str..GetContent(_SaveVScript)
			end
		end
		return str
	end
	
	local function RefreshInit(addon)		
		local code = addon[2]["Content"]
		
		if not code or code == "" then
			addon[2]["Content"] = GetContent(_InitScript)..GetSaveVariables(addon)
			return
		end

		if strfind(code, "_Addon:AddSavedVariable%b()") then
			local index = strfind(code, "_Addon:AddSavedVariable%b()") - 1
			
			code = gsub(code, "_Addon:AddSavedVariable%b()\n", "")

			addon[2]["Content"] = strsub(code, 1, index)..GetSaveVariables(addon)..strsub(code, index + 1)			
		else
			addon[2]["Content"] = code..GetSaveVariables(addon)
		end
		
		_Addon:FireEvent("IGAS_STUDIO_FILERELOAD_REQUIRE", addon[2])
	end

	local function Clear()
		for _, v in ipairs(_TOC_FORMAT) do
			if v.Name == "Name" and Container:GetChild("txtName").Editable then
				Container:GetChild("txtName").Text = v.Default or ""
			elseif v.Type == "String" or v.Type == "Number" then
				Container:GetChild("txt"..v.Name).Text = ""
			elseif v.Type == "Set" then
				Container:GetChild("set"..v.Name):Clear()
			elseif v.Type == "Boolean" then
				Container:GetChild("chk"..v.Name).Checked = false
			end
		end
	end
	
	local function LoadAddonInfo(addon)
		local info = addon and addon[0]
		
		if info then		
			for _, v in ipairs(_TOC_FORMAT) do
				if v.Type == "String" or v.Type == "Number" then
					Container:GetChild("txt"..v.Name).Text = info[v.Name] or ""
				elseif v.Type == "Set" then
					Container:GetChild("set"..v.Name):Load(info)
				elseif v.Type == "Boolean" then
					if info[v.Name] == v.True then
						Container:GetChild("chk"..v.Name).Checked = true
					else
						Container:GetChild("chk"..v.Name).Checked = false
					end
				end
			end
		else
			Clear()
		end
	end
	
	local function SaveAddonInfo()
		local name = Container:GetChild("txtName").Text
		
		-- Create new addon
		if not IGAS_STUDIO_DB.FileDB[name] then
			substr["Addon"] = name
			
			IGAS_STUDIO_DB.FileDB[name] = {}
			IGAS_STUDIO_DB.FileDB[name][0] = { ["Name"] = name, ["Type"] = "Toc", }
			IGAS_STUDIO_DB.FileDB[name][1] = { ["Name"] = "Localization", ["Type"] = "Folder", }
			IGAS_STUDIO_DB.FileDB[name][2] = { ["Type"] = "Script", ["Name"] = "Initialize", ["Content"] = "", }
			IGAS_STUDIO_DB.FileDB[name][3] = { ["Name"] = "Script", ["Type"] = "Folder", }
			IGAS_STUDIO_DB.FileDB[name][4] = { ["Name"] = "Widget", ["Type"] = "Folder", }
			IGAS_STUDIO_DB.FileDB[name][5] = { ["Name"] = "Frame", ["Type"] = "Folder", }
			IGAS_STUDIO_DB.FileDB[name][6] = { ["Name"] = name, ["Type"] = "Script", ["Content"] = GetContent(_AddonScript) }
			IGAS_STUDIO_DB.FileDB[name].__RegisterEventList = {}
		end
		
		local info = IGAS_STUDIO_DB.FileDB[name][0]
		
		for _, v in ipairs(_TOC_FORMAT) do
			if v.Type == "String" or v.Type == "Number" then
				if v.Validate and type(v.Validate) == "function" then
					Container:GetChild("txt"..v.Name).Text = v.Validate(Container:GetChild("txt"..v.Name).Text)
				end
				info[v.Name] = Container:GetChild("txt"..v.Name).Text
			elseif v.Type == "Set" then
				Container:GetChild("set"..v.Name):Save(info)
			elseif v.Type == "Boolean" then
				if Container:GetChild("chk"..v.Name).Checked then
					info[v.Name] = v.True
				else
					info[v.Name] = v.False
				end
			end
		end
		
		-- Initialize Script File
		RefreshInit(IGAS_STUDIO_DB.FileDB[name])
	end

	function btnCancel:OnClick()
		self.Parent.Visible = false
	end
	
	function btnSave:OnClick()
		local name = Container:GetChild("txtName").Text
		
		if strtrim(name or "") == "" then
			return
		end
		
		if IGAS:IsAddonExist(name) then
			IGAS:MsgBox(L["There is an addon with that name."])
			return
		end
		
		if Container:GetChild("txtName").Editable and IGAS_STUDIO_DB.FileDB[name] then
			IGAS:MsgBox(L["There is an addon with that name."])
			return
		end
		
		SaveAddonInfo()
		self.Parent.Visible = false
		return self.Parent:FireEvent("IGAS_STUDIO_ADDONINFO_SAVE", name)
	end
	
	------------------------------------------------
	-- Custom Events
	------------------------------------------------
	frm:RegisterEvent("IGAS_STUDIO_ADDONINFO_REQUIRE")
	function frm:IGAS_STUDIO_ADDONINFO_REQUIRE(addon)
		LoadAddonInfo(addon)
		if strtrim(Container:GetChild("txtName").Text) ~= "" then
			Container:GetChild("txtName").Editable = false
		else
			Container:GetChild("txtName").Editable = true
		end
		self.Visible = true
	end
end